﻿// <copyright file="Material2Controller.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>

namespace MesAPI.Controllers.Material
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using MesAPI.Extensions.AuthContext;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.EntityFrameworkCore;
    using PublicData;
    using PublicFunction;
    using XinjeMesProgram.Entities;
    using XinjeMesProgram.Entities.Material;
    using XinjeMesProgram.Models;
    using XinjeMesProgram.Models.Material;

    /// <summary>
    /// 物料追踪主表控制器.
    /// </summary>
    [ApiController] // [ApiController] 必须加不然你调用不了参数
    [Authorize]
    public class Material2Controller : ControllerBase
    {
#pragma warning disable SA1000 // Keywords should be spaced correctly
#pragma warning disable CS8602 // 解引用可能出现空引用。
        private readonly ResponseModel response = new();

        /// <summary>
        /// 主表查询.
        /// </summary>
        /// <param name="data">查询条件.</param>
        /// <returns>返回主表记录.</returns>
        [Route("/api/v1/material/materialRecord")]
        [HttpPost]
        public ResponseModel MaterialRecord(MaterialRecordModel data)
        {
            using (var context = new FactoryMesContext())
            {
                var query1 = from m2 in context.MaterialTracking2
                             where m2.ProductionDepartment == data.product_category
                             && (data.abnormal == 100 ? (m2.Abnormal == 0 || m2.Abnormal == 1 || m2.Abnormal == 2) : m2.Abnormal == data.abnormal) // 按照生产部门、流程状态筛选
                             orderby m2.Documentnumbern descending
                             select new MaterialDataModel
                             {
                                 Id = m2.Id, // 唯一Id
                             };
                List<MaterialDataModel> list1 = query1.ToList();
                var info1 = context.MaterialTracking2.FirstOrDefault();
                for (int i = 0; i < list1.Count; i++)
                {
                    var info2 = context.MaterialTracking2.FirstOrDefault(x => x.Id == list1[i].Id);
                    var info3 = context.MaterialTracking3.FirstOrDefault(x => x.Id2 == list1[i].Id && x.State == 1);
                    var info4 = context.MaterialTracking3.FirstOrDefault(x => x.Id2 == list1[i].Id && x.State == 2);
                    if (info1 != null)
                    {
                        if (info2.ProductionQuantity != null && int.Parse(info2.ProductionQuantity) > 0 && int.Parse(info2.ProductionQuantity) % 1 == 0)
                        {
                            string faultNumber = context.MaterialTracking3.Where(x => x.Id2 == list1[i].Id && x.State == 2).ToList().Count.ToString();
                            string maintenanceNumber = (double.Parse(faultNumber) / double.Parse(info2.ProductionQuantity) * 1000).ToString("0.##");
                            info2.FaultNumber = faultNumber;
                            info2.MaintenanceNumber = maintenanceNumber + "‰";
                        }

                        if (info3 == null && info4 == null)
                        {
                            info2.Abnormal = 0;
                        }
                        else if (info3 == null && info4 != null)
                        {
                            info2.Abnormal = 2;
                        }
                        else
                        {
                            info2.Abnormal = 1;
                        }

                        var info5 = context.MaterialTracking3.Where(x => x.Id2 == list1[i].Id && x.Condition == 0); // 在库
                        var info6 = context.MaterialTracking3.Where(x => x.Id2 == list1[i].Id && x.Condition == 1); // 不在库
                        info2.QuantityInStock = info5.Count().ToString();
                        info2.NotInStockQuantity = info6.Count().ToString();

                        context.SaveChanges();
                    }
                    else
                    {
                        break;
                    }
                }

                var query2 = from m in context.MaterialTracking // content后跟数据库实体名称
                             select new MaterialModel
                             {
                                 Title = m.Title,
                                 Key = m.Key,
                                 Width = m.Width,
                                 Align = m.Align,
                             };

                var query3 = from m2 in context.MaterialTracking2
                             where m2.ProductionDepartment == data.product_category
                             && (data.abnormal == 100 ? (m2.Abnormal == 0 || m2.Abnormal == 1 || m2.Abnormal == 2) : m2.Abnormal == data.abnormal) // 按照生产部门、流程状态筛选
                             select new MaterialDataModel
                             {
                                 Id = m2.Id, // 唯一Id
                                 Documentnumbern = m2.Documentnumbern, // 文件编号
                                 Analyst = m2.Analyst, // 分析专员
                                 Number = m2.Number, // ECN编号
                                 ReleaseTime = m2.ReleaseTime, // ECN发布时间
                                 ChangeContent = m2.ChangeContent, // 变更内容
                                 ReasonForChange = m2.ReasonForChange, // 变更原因
                                 WorkOrder = m2.WorkOrder, // 工单
                                 WorkOrderCompletionDate = m2.WorkOrderCompletionDate, // 工单完成日期
                                 SerialNumber = m2.SerialNumber, // 序列号段
                                 ProductionCode = m2.ProductionCode, // 产片代码
                                 ProductModel = m2.ProductModel, // 产品型号
                                 TrackMaterialCode = m2.TrackMaterialCode, // 跟踪物料代码
                                 TrackingMaterialName = m2.TrackingMaterialName, // 跟踪物料名称
                                 TrackMaterialModel = m2.TrackMaterialModel, // 跟踪物料型号
                                 BitNumber = m2.BitNumber, // 位号
                                 ProductionQuantity = m2.ProductionQuantity, // 生产数量
                                 QuantityInStock = m2.QuantityInStock, // 在库数量
                                 NotInStockQuantity = m2.NotInStockQuantity, // 不在库数量
                                 FaultNumber = m2.FaultNumber, // 故障数
                                 MaintenanceNumber = m2.MaintenanceNumber, // 故障率
                                 EndDate = m2.EndDate, // 跟踪月份（3、6、9、12）
                                 Remarks = m2.Remarks, // 备注
                                 Abnormal = m2.Abnormal, // 是否异常，1：异常 0：正常
                             };

                List<MaterialModel> list2 = query2.ToList();
                List<MaterialDataModel> list3 = query3.ToList();

                var sortedList = list3.OrderByDescending(item =>
                {
                    // 尝试从Documentnumbern字段中解析出数字部分
                    if (!string.IsNullOrEmpty(item.Documentnumbern))
                    {
                        var parts = item.Documentnumbern.Split('-');
                        if (parts.Length > 1 && int.TryParse(parts[1], out int numericPart))
                        {
                            // 成功解析数字部分就返回这个数字用于排序
                            return numericPart;
                        }
                    }

                    // 解析失败返回0，或者您可以选择抛出一个异常
                    return 0;
                }).ToList();

                // 筛选查询
                foreach (var item in data.items)
                {
                    var s = list2.Where(x => string.Equals(x.Title, item.Index)).ToList();
                    foreach (var item2 in s)
                    {
                        if (!string.IsNullOrEmpty(item.Value))
                        {
                            switch (item2.Key)
                            {
                                case "documentnumbern": // 文件编号
                                    list3 = list3.Where(x => x.Documentnumbern.Contains(item.Value)).ToList();
                                    break;
                                case "analyst": // 分析专员
                                    list3 = list3.Where(x => x.Analyst.Contains(item.Value)).ToList();
                                    break;
                                case "serialNumber": // 序列号段
                                    list3 = list3.Where(x => x.SerialNumber.Contains(item.Value)).ToList();
                                    break;
                                case "productModel": // 产品型号
                                    list3 = list3.Where(x => x.ProductModel.Contains(item.Value)).ToList();
                                    break;
                                case "number": // ECN编号
                                    list3 = list3.Where(x => x.Number.Contains(item.Value)).ToList();
                                    break;
                                case "releaseTime": // ECN发布时间
                                    list3 = list3.Where(x => x.ReleaseTime.Contains(item.Value)).ToList();
                                    break;
                                case "changeContent": // 变更内容
                                    list3 = list3.Where(x => x.ChangeContent.Contains(item.Value)).ToList();
                                    break;
                                case "ReasonForChange": // 变更原因
                                    list3 = list3.Where(x => x.ReasonForChange.Contains(item.Value)).ToList();
                                    break;
                                case "workOrder": // 工单
                                    list3 = list3.Where(x => x.WorkOrder.Contains(item.Value)).ToList();
                                    break;
                                case "workOrderCompletionDate": // 工单完成日期
                                    list3 = list3.Where(x => x.WorkOrderCompletionDate.Contains(item.Value)).ToList();
                                    break;
                                case "productionCode": // 产品代码
                                    list3 = list3.Where(x => x.ProductionCode.Contains(item.Value)).ToList();
                                    break;
                                case "trackMaterialCode": // 跟踪物料代码
                                    list3 = list3.Where(x => x.TrackMaterialCode.Contains(item.Value)).ToList();
                                    break;
                                case "trackingMaterialName": // 跟踪物料名称
                                    list3 = list3.Where(x => x.TrackingMaterialName.Contains(item.Value)).ToList();
                                    break;
                                case "trackMaterialModel": // 跟踪物料型号
                                    list3 = list3.Where(x => x.TrackMaterialModel.Contains(item.Value)).ToList();
                                    break;
                                case "endDate": // 跟踪月份
                                    list3 = list3.Where(x => x.EndDate.Contains(item.Value)).ToList();
                                    break;
                                case "bitNumber": // 位号
                                    list3 = list3.Where(x => x.BitNumber.Contains(item.Value)).ToList();
                                    break;
                                case "productionQuantity": // 生产数量/台
                                    list3 = list3.Where(x => x.ProductionQuantity.Contains(item.Value)).ToList();
                                    break;
                                case "maintenanceNumber": // 故障数
                                    list3 = list3.Where(x => x.MaintenanceNumber.Contains(item.Value)).ToList();
                                    break;
                                case "faultNumber": // 故障率
                                    list3 = list3.Where(x => x.FaultNumber.Contains(item.Value)).ToList();
                                    break;
                                case "remarks": // 备注
                                    list3 = list3.Where(x => x.Remarks.Contains(item.Value)).ToList();
                                    break;
                                default:
                                    break;
                            }
                        }
                    }
                }

                // 正常查询
                if (data.oN1 == 0)
                {
                    this.response.SetData(sortedList.ListPaged(data.currentPage, data.pageSize), sortedList.Count);
                }

                // 主表数据导出
                else if (data.oN1 == 1)
                {
                    string currentTimeStamp = DateTime.Now.ToString("yyyyMMdd_HHmmss"); // 时间戳
                    string randomString = Path.GetRandomFileName().Replace(".", string.Empty); // 随机字符串
                    string fileName = $"file_{currentTimeStamp}_{randomString}.csv"; // 定义文件名
                    string filePath = Path.Combine("C:\\WebSite\\XinjeMesApi\\wwwroot\\main", fileName);
                    using (StreamWriter writer = new(filePath, true, Encoding.UTF8))
                    {
                        string abnormalText = string.Empty;

                        writer.WriteLine("唯一ID,文件编号,ECN编号,ECN发布时间,变更内容,变更原因,工单,工单完成日期,序列号段,产片代码,产品型号," +
                            "跟踪物料代码,跟踪物料名称,跟踪物料型号,位号,生产数量,跟踪月数,故障数,故障率,备注,是否异常");
                        foreach (MaterialDataModel item in list3)
                        {
                            abnormalText = (item.Abnormal == 0) ? "正常" : (item.Abnormal == 1 ? "待核对" : "数据异常");

                            writer.WriteLine($"{item.Id},{item.Documentnumbern},{item.Number},{item.ReleaseTime},\"{item.ChangeContent}\"," +
                                $"\"{item.ReasonForChange}\",\"{item.WorkOrder}\",{item.WorkOrderCompletionDate},\"{item.SerialNumber}\"," +
                                $"{item.ProductionCode},{item.ProductModel},{item.TrackMaterialCode},{item.TrackingMaterialName},{item.TrackMaterialModel}," +
                                $"{item.BitNumber},{item.ProductionQuantity},{item.EndDate},{item.FaultNumber},{item.MaintenanceNumber}," +
                                $"\"{item.Remarks}\",{abnormalText}");
                        }
                    }

                    this.response.SetSuccess($"导出成功！路径为：{filePath}");
                }
            }

            return this.response;
        }

        /// <summary>
        /// 主表(新增/修改）数据.
        /// </summary>
        /// <param name="data">更改内容.</param>
        /// <returns>返回（新增/修改）状态.</returns>
        [Route("/api/v1/material/materialRecordAdd")]
        [HttpPost]
        public ResponseModel MaterialRecordAdd(MaterialDataModel data)
        {
            using (FactoryMesContext context = new())
            {
                var info1 = context.MaterialTracking2.FirstOrDefault(x => x.Id == data.Id);

                // 新增
                if (info1 == null)
                {
                    var info2 = context.MaterialTracking2.OrderByDescending(x => x.Documentnumbern).FirstOrDefault(x => x.ProductionDepartment == data.Product_category);
                    string number = string.Empty;

                    var result1 = from m2 in context.MaterialTracking2
                                  where m2.ProductionDepartment == data.Product_category
                                  select new MaterialDataModel
                                  {
                                      Documentnumbern = m2.Documentnumbern, // 文件编号
                                  };
                    List<MaterialDataModel> list1 = result1.ToList();
                    var sortedList = list1.OrderByDescending(item =>
                    {
                        // 尝试从Documentnumbern字段中解析出数字部分
                        if (!string.IsNullOrEmpty(item.Documentnumbern))
                        {
                            var parts = item.Documentnumbern.Split('-');
                            if (parts.Length > 1 && int.TryParse(parts[1], out int numericPart))
                            {
                                // 成功解析数字部分就返回这个数字用于排序
                                return numericPart;
                            }
                        }

                        // 解析失败返回0，或者您可以选择抛出一个异常
                        return 0;
                    }).ToList();

                    // 有记录
                    if (sortedList.Count != 0)
                    {
                        number = (Convert.ToInt32(sortedList[0].Documentnumbern.Split('-')[1]) + 1).ToString();
                    }

                    // 无记录
                    else
                    {
                        number = "1";
                    }

                    MaterialDataEntity material2 = new()
                    {
                        Id = RandomHelper.GetRandomizer(12, true, false, true, true),
                        Documentnumbern = data.Documentnumbern + number,
                        Number = data.Number, // ECN编号
                        Analyst = AuthContextService.CurrentUser.UserName, // 分析专员
                        ReleaseTime = data.ReleaseTime, // ECN发布时间
                        ChangeContent = data.ChangeContent, // 变更内容
                        ReasonForChange = data.ReasonForChange, // 变更原因
                        WorkOrder = data.WorkOrder, // 工单
                        WorkOrderCompletionDate = data.WorkOrderCompletionDate, // 工单完成日期
                        SerialNumber = data.SerialNumber1, // 序列号段
                        ProductionCode = data.ProductionCode, // 产品代码
                        ProductModel = data.ProductModel, // 产品型号
                        TrackMaterialCode = data.TrackMaterialCode, // 跟踪物料代码
                        TrackingMaterialName = data.TrackingMaterialName, // 跟踪物料名称
                        TrackMaterialModel = data.TrackMaterialModel, // 跟踪物料型号
                        EndDate = data.EndDate, // 跟踪月份
                        FaultNumber = string.Empty, // 故障数
                        MaintenanceNumber = string.Empty, // 故障率
                        BitNumber = data.BitNumber, // 位号
                        ProductionQuantity = data.ProductionQuantity, // 生产数量
                        Remarks = data.Remarks, // 备注
                        Abnormal = 0, // data.abnormal, // 是否异常， 0：正常 1：待核对 2：异常
                        ProductionDepartment = data.Product_category, // 生产部门
                    };
                    context.MaterialTracking2.Add(material2);
                    context.SaveChanges();
                }

                // 修改
                else
                {
                    info1.Number = data.Number; // ECN编号
                    info1.ReleaseTime = data.ReleaseTime; // ECN发布时间
                    info1.ChangeContent = data.ChangeContent; // 变更内容
                    info1.ReasonForChange = data.ReasonForChange; // 变更原因
                    info1.WorkOrder = data.WorkOrder; // 工单
                    info1.WorkOrderCompletionDate = data.WorkOrderCompletionDate; // 工单完成日期
                    info1.SerialNumber = data.SerialNumber1; // 序列号段
                    info1.ProductionCode = data.ProductionCode; // 产品代码
                    info1.ProductModel = data.ProductModel; // 产品型号
                    info1.TrackMaterialCode = data.TrackMaterialCode; // 跟踪物料代码
                    info1.TrackingMaterialName = data.TrackingMaterialName; // 跟踪物料名称
                    info1.TrackMaterialModel = data.TrackMaterialModel; // 跟踪物料型号
                    info1.BitNumber = data.BitNumber; // 位号
                    info1.ProductionQuantity = data.ProductionQuantity; // 生产数量
                    info1.Remarks = data.Remarks; // 备注
                    info1.ProductionDepartment = data.Product_category; // 生产部门
                    context.SaveChanges();
                }
            }

            return this.response;
        }

        /// <summary>
        /// 主表及子表数据删除 .
        /// </summary>
        /// <param name="id">需求主体 .</param>
        /// <param name="xis">判断操作类型 .</param>
        /// <returns> .</returns>
        [Route("/api/v1/material/materialRecordDelete")]
        [HttpGet]
        public ResponseModel MaterialRecordDelete(string? id, string? xis)
        {
            using (FactoryMesContext context = new())
            {
                var info1 = context.MaterialTracking2.FirstOrDefault(x => x.Id == id); // 主表
                if (xis == "2")
                {
                    if (info1 != null)
                    {
                        string sQL1 = string.Format("DELETE FROM MaterialTracking2 WHERE ID = '{0}';select a.ID  from MaterialTracking2 a  where a.ID='{0}'", id);
                        string sQL2 = string.Format("DELETE FROM MaterialTracking3 WHERE ID2 = '{0}';select a.ID2  from MaterialTracking3 a  where a.ID2 = '{0}'", id);
                        _ = context.Deletedata.FromSqlRaw(sQL1).ToList();
                        _ = context.Deletedata.FromSqlRaw(sQL2).ToList();  // 执行SQL
                    }
                    else
                    {
                        throw new ArgumentException("Id should not be null or empty.", nameof(id));
                    }
                }
            }

            return this.response;
        }
    }
}